#ifndef __SMARTHOMEMONITORSERVER_HPP__
#define __SMARTHOMEMONITORSERVER_HPP__

#include "EventLoop.hpp"
#include "Message.hpp"
#include "TcpServer.hpp"
#include "ThreadPool.hpp"
#include "BusinessTask.hpp"
#include "UserManager.hpp"
#include "GetAvPacket.hpp"
#include "Configuration.hpp"
#include <shadow.h>
#include <iostream>
#include <functional>
using std::cout;
using std::endl;
using std::stoi;

namespace wd{

class smartHomeMonitorServer{
    using Elemtype = std::function<void()>;
public:
    smartHomeMonitorServer(int threadnum,int que_len,int port, string ip)
    :_threadpool(threadnum,que_len)
    ,_tcpserver(port,ip)
    {

    }
    void start(){
        using namespace std::placeholders;
        _tcpserver.setAllCallbacks(
                                   std::bind(&smartHomeMonitorServer::onConnection,this,_1),
                                   std::bind(&smartHomeMonitorServer::onMessage,this,_1),
                                   std::bind(&smartHomeMonitorServer::onClose,this,_1));
        _threadpool.start();
        //在一开始就要把拉去视频信息的子线程加入
        wd::Configuration* config = wd::Configuration::getInstance("./server.conf");
        map<string,string> &config_map = config->getConfigMap();
        int camera_id = stoi(config_map["camera_id"]);
        string rtmp = config_map["rtmp"];
        wd::GetAvPacket getpacket(camera_id,rtmp);
        _threadpool.addTask(std::bind(&wd::GetAvPacket::process,getpacket));

        _tcpserver.start();
    }

    void stop(){
        _threadpool.stop();
        _threadpool.stop();
    }


private:
    void onConnection(wd::TcpConnectionptr tcpconn){
        printf("a new clienfd connected.\n");

    }
    
    void onMessage(wd::TcpConnectionptr tcpconn){
        wd::Packet packet;
        int ret = tcpconn->receive(packet);
        cout << "packet type: " << packet.type << endl;
        cout << "packet msg: " << packet.msg << endl;
        printf("onMessage,recv %d bytes\n",ret);
        //区分不同的情况,交给子线程处理
        if(packet.type == TASK_LOGIN_SECTION1){
            UserLoginSection1 logintask(packet,tcpconn);
            _threadpool.addTask(std::bind(&UserLoginSection1::process,logintask));
        }else if(packet.type == TASK_LOGIN_SECTION2){
            UserLoginSection2 logintask(packet,tcpconn);
            _threadpool.addTask(std::bind(&UserLoginSection2::process,logintask));
        }else if(packet.type == TASK_REGISTER_SECTION1){
            UserRegisterSection1 registertask(packet,tcpconn);
            _threadpool.addTask(std::bind(&UserRegisterSection1::process,registertask));
        }else if(packet.type == TASK_REGISTER_SECTION2){
            UserRegisterSection2 registertask(packet,tcpconn);
            _threadpool.addTask(std::bind(&UserRegisterSection2::process,registertask));
            
        }else if(packet.type == TASK_GET_CAMERA_DATA){
            /* cout << "get a video requset" << endl; */
            //此处只需要将用户信息加入单例
            UserManger* user_m =  UserManger::getInstance();
            shared_ptr<User> puser(new User); 
            int camera_id = std::stoi(packet.msg);
            puser->set_camera_id(camera_id);
            user_m->add_user_info(tcpconn,puser);
            

            ////测试回复消息
            //TLV2 tlv;
            //tlv.type = TASK_GET_CAMERA_DATA_OK;
            //tlv.length = 0;
            //tcpconn->sendInLoop(tlv);
        }
    }
    
    void onClose(wd::TcpConnectionptr tcpconn){
        printf("a clienfd closed.\n");
        UserManger* user_m =  UserManger::getInstance();
        user_m->del_user_info(tcpconn);

    }



private:
    ThreadPool _threadpool;
    wd::TcpServer _tcpserver;
};

}



#endif // __SMARTHOMEMONITORSERVER_HPP__

